#include <GL/glut.h>
#include <stdlib.h>

#define MUNDO 6.0f
//Variables globales que guardan el tope de las coordenadas de mundo
float xMax, yMax;
float xRot, yRot, zRot, scale;
float angulosDedos[5], angulosFalanges[5];
int solid;
int play;

void inicializar (void);
void redimensiona (int alto, int ancho);
void dibuja (void);
void teclado (unsigned char key, int cx, int cy);
void tecladoEspecial (int key, int cy, int cx);
void dibujaEscena (void);
void dibujaFalange(void);
void dibujaDedo(float);
void dibujaMano(void);

int main(int argc, char** argv) {

   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
   glutInitWindowSize (640, 480);
   glutInitWindowPosition (100, 105);
   glutCreateWindow ("Mano");
   inicializar();

   glutDisplayFunc(dibuja);
   glutReshapeFunc(redimensiona);
   glutKeyboardFunc(teclado);
   glutSpecialFunc(tecladoEspecial);

   glutMainLoop();

   return 0;
}

void inicializar () {
   //glClearColor(0.0, 0.0, 0.0, 0.0);
   glClearColor(1.0, 1.0, 1.0, 1.0);
   glEnable(GL_DEPTH_TEST);
   solid = 0;
   xRot = yRot = zRot = 0.0;
   scale = 1.0;
   play = 0;
   int i;
   for (i = 0; i < 5; i++) {
	   angulosDedos[i] = 30.0;
	   angulosFalanges[i] = 30.0;
   }
}

void redimensiona (int ancho, int alto) {
   float aspect;

   glViewport (0, 0, ancho, alto);
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();

   if (alto == 0){
   	  alto = 1;
   }

   aspect = (float) ancho / (float) alto;

   if (ancho <= alto) {
   	  glOrtho(-MUNDO, MUNDO, -MUNDO/aspect, MUNDO/aspect, -(MUNDO + 2.0), MUNDO + 2.0);

   } else {
   	  glOrtho(-MUNDO * aspect, MUNDO * aspect, -MUNDO, MUNDO, -(MUNDO + 2.0), MUNDO + 2.0);
   }

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}

void teclado (unsigned char key, int cx, int cy) {

	switch (key) {
		case 27:
		   exit(0);
		break;

		case '+':
			scale += 0.1;
		break;

		case '-':
			scale -= 0.1;
		break;

		case 'o':
			solid = !(solid);
		break;

		case 'a':
			play = !(play);
		break;

		default: break;
	}

	glutPostRedisplay();
}

void tecladoEspecial (int key, int cy, int cx) {

	switch (key) {
		case GLUT_KEY_UP:
			xRot += 5.0;
		break;

		case GLUT_KEY_DOWN:
			xRot -= 5.0;
		break;

		case GLUT_KEY_LEFT:
			yRot -= 5.0;
		break;

		case GLUT_KEY_RIGHT:
			yRot += 5.0;
		break;

		case GLUT_KEY_PAGE_UP:
			zRot += 5.0;
		break;

		case GLUT_KEY_PAGE_DOWN:
			zRot -= 5.0;
		break;

		default: break;
	}

	glutPostRedisplay();
}

void dibuja (void) {

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glPushMatrix();
		glRotatef(xRot, 1.0, 0.0, 0.0);
		glRotatef(yRot, 0.0, 1.0, 0.0);
		glRotatef(zRot, 0.0, 0.0, 1.0);
		glScalef(scale, scale, scale);
		glColor3f(0.0, 0.0, 0.0);
		dibujaEscena();
	glPopMatrix();

	glutSwapBuffers();
}

void dibujaEscena () {
	glPushMatrix();
		dibujaMano();
	glPopMatrix();
}

void dibujaFalange(void) {
	//glColor3f(1.0, 0.0, 0.0);
	solid ? glutSolidSphere(0.25, 10.0, 10.0) : glutWireSphere(0.25, 10.0, 10.0);
	glPushMatrix();
		glTranslatef(0.0, 0.0, -1.0);
		glPushMatrix();
			glScalef(0.5, 0.5, 1.5);
			//glColor3f(1.0, 1.0, 0.0);
			solid ? glutSolidCube(1.0) : glutWireCube(1.0);
		glPopMatrix();
	glPopMatrix();
}

void dibujaDedo(float angle) {
	dibujaFalange();
	glPushMatrix();
		glTranslatef(0.0, 0.0, -1.95);
		glRotatef(angle, 1.0, 0.0, 0.0);
		glScalef(0.75, 0.75, 0.75);
		dibujaFalange();
	glPopMatrix();
}

void dibujaMano(void) {
	glPushMatrix();
		//Muñeca
		glPushMatrix();
			glTranslatef(0.0, -0.375, 0.0);
			glScalef(2.0, 0.75, 0.75);
			//glColor3f(1.0, 0.0, 0.0);
			solid ? glutSolidCube(1.0) : glutWireCube(1.0);
		glPopMatrix();
		//Palma
		glPushMatrix();
			glTranslatef(0.0, 0.25, -1.3);
			glScalef(3.0, 0.5, 3.0);
			//glColor3f(1.0, 1.0, 0.0);
			solid ? glutSolidCube(1.0) : glutWireCube(1.0);
		glPopMatrix();
		//Dedo 1
		glPushMatrix();
			glTranslatef(1.25, 0.25, -3.0);
			glRotatef(angulosDedos[0], 1.0, 0.0, 0.0);
			dibujaDedo(angulosFalanges[0]);
		glPopMatrix();
		//Dedo 2
		glPushMatrix();
			glTranslatef(0.45, 0.25, -3.0);
			glRotatef(angulosDedos[1], 1.0, 0.0, 0.0);
			dibujaDedo(angulosFalanges[1]);
		glPopMatrix();
		//Dedo 3
		glPushMatrix();
			glTranslatef(-0.45, 0.25, -3.0);
			glRotatef(angulosDedos[2], 1.0, 0.0, 0.0);
			dibujaDedo(angulosFalanges[2]);
		glPopMatrix();
		//Dedo 4
		glPushMatrix();
			glTranslatef(-1.25, 0.25, -3.0);
			glRotatef(angulosDedos[3], 1.0, 0.0, 0.0);
			dibujaDedo(angulosFalanges[3]);
		glPopMatrix();
		//Pulgar
		glPushMatrix();
			glTranslatef(-1.5, 0.25, -1.5);
			glRotatef(angulosDedos[4], 0.0, 1.0, 0.0);
			glScalef(1.25, 1.25, 0.8);
			dibujaDedo(angulosFalanges[4]);
		glPopMatrix();
	glPopMatrix();
}

